#include<mutex>
#include<iostream>
using namespace std;

//1.只能在栈上创建对象
class StackOnly
{
public:
    static StackOnly GetStackObj()
    {
        return StackOnly();
    }
private:
    StackOnly()
    {}
    void* operator new(size_t size) = delete;
    void operator delete(void* p) = delete;
};

//2.只能在堆上创建对象
class HeapOnly
{
public:
    static HeapOnly* GetHeapObj()
    {
        return new HeapOnly();
    }
private:
    HeapOnly()
    {}
    HeapOnly(const HeapOnly&) = delete;
};

class HeapOnly_v2
{
public:
    HeapOnly_v2()
    {
        str = new char[20];
    }
    static HeapOnly_v2* GetHeapObj()
    {
        return new HeapOnly_v2();
    }
    void Destroy()
    {
        cout << "Destroy...." << endl;
        delete[] str;
        operator delete(this);
    }
private:
    ~HeapOnly_v2()
    {}
    char* str;
};
//3.单例模式
class SingLeton_Hungry
{
public:
    static SingLeton_Hungry& GetInstance() //注意是传引用返回
    {
        return instance;
    }
private:
    SingLeton_Hungry()
    {}
    SingLeton_Hungry(const SingLeton_Hungry&) = delete;
    SingLeton_Hungry& operator=(const SingLeton_Hungry&) = delete;
private:
    static SingLeton_Hungry instance;
};
SingLeton_Hungry SingLeton_Hungry::instance;


class SingLeton_lazy
{
public:
    static SingLeton_lazy* GetInstance()
    {
        if (instance == nullptr)
        {
            unique_lock<mutex> ul(mtx);
            if (instance == nullptr)
            {
                instance = new SingLeton_lazy();
            }
        }
        return instance;
    }
private:
    SingLeton_lazy() {}
    SingLeton_lazy(const SingLeton_lazy&) = delete;
    SingLeton_lazy& operator=(const SingLeton_lazy&) = delete;
private:
    static mutex mtx;
    static SingLeton_lazy* instance;
};
mutex SingLeton_lazy::mtx;
SingLeton_lazy* SingLeton_lazy::instance = nullptr;
//4.设计一个类防拷贝
class NonCopy
{
public:
    NonCopy()
    {}
private:
    NonCopy(const NonCopy&) = delete;
    NonCopy& operator=(const NonCopy&) = delete;
};
//5.设计一个类不能被继承
class NonExtend  final
{
    //c++98:
    //private:
    // NonExtend()
    // {}
};
int main()
{
    HeapOnly_v2* hp = new HeapOnly_v2();
    hp->Destroy();
    return 0;
}
